package com.blog.wu.myblog.shiro;

import com.blog.wu.myblog.entity.UserInfo;
import com.blog.wu.myblog.service.LoginLogService;
import com.blog.wu.myblog.service.UserInfoService;
import com.blog.wu.myblog.util.HttpUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @Author wuyanshen
 * @Date 2018-11-05 2:08 PM
 * @Discription shiro表单认证过滤器
 */
@Service
public class ShiroFormFilter extends FormAuthenticationFilter {

    private static final Logger logger = LoggerFactory.getLogger(FormAuthenticationFilter.class);

    @Autowired
    private LoginLogService loginLogService;

    @Autowired
    private UserInfoService userInfoService;

    /**
     * 组装登录信息
     *
     * @return
     * @Date 2018/12/28 3:18 PM
     * @Author wuyanshen
     */
    @Override
    protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {

        //自定义用户名、密码
        setUsernameParam("userAccount");
        setPasswordParam("userPassword");

        HttpServletRequest req = (HttpServletRequest) request;
        //从页面获取用户名、密码
        String userAccount = getUsername(req);
        String password = getPassword(req);

        return new UsernamePasswordToken(userAccount, password);
    }

    /**
     * 登录成功后调用
     *
     * @param token
     * @param subject
     * @param request
     * @param response
     * @return boolean
     * @Date 2018/12/28 3:18 PM
     * @Author wuyanshen
     */
    @Override
    protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, ServletResponse response) throws Exception {
        //登录时间
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Session session = SecurityUtils.getSubject().getSession();
        UserInfo userInfo = (UserInfo) SecurityUtils.getSubject().getPrincipal();
        session.setAttribute("loginTime", format.format(new Date()));
        userInfo.setIp(HttpUtils.getIp((HttpServletRequest) request));
        session.setAttribute("userinfo", userInfo);
        logger.info("当前的操作系统是:" + HttpUtils.getOS());
        logger.info("当前的操作系统的MAC地址是:" + HttpUtils.getLocalMac());

        String url = getSuccessUrl();
        return super.onLoginSuccess(token, subject, request, response);
    }

    /**
     * 登录失败后调用
     *
     * @param token
     * @param e
     * @param request
     * @param response
     * @return boolean
     * @Date 2018/12/28 3:18 PM
     * @Author wuyanshen
     */
    @Override
    protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
        String exception = e.getClass().getName();
        if (UnknownAccountException.class.getName().equals(exception)) {
            request.setAttribute("message", "用户名不存在，请重试");
        } else if (IncorrectCredentialsException.class.getName().equals(exception)) {
            request.setAttribute("message", "用户密码错误，请重试");
        } else {
            request.setAttribute("message", "系统出现问题，请联系管理员");
            //打印到控制台
            e.printStackTrace();
        }
        return true;
    }


    /**
     * 登录成功之后跳转URL
     */
    @Override
    public String getSuccessUrl() {
        return super.getSuccessUrl();
    }

    /**
     * 必须重写这个方法，否则，登录成功后会找不到页面
     *
     * @param
     * @return
     * @Date 2018/12/28 3:19 PM
     * @Author wuyanshen
     */
    @Override
    protected void issueSuccessRedirect(ServletRequest request,
                                        ServletResponse response) throws Exception {
        WebUtils.issueRedirect(request, response, getSuccessUrl(), null, true);
    }


}
